home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / protect-your-privacy / p.g.p. / pgpsendmail / source / expandalias.c next >
C/C++ Source or Header  |  1996-02-26  |  12KB  |  362 lines

  1. /*
  2.  *      $Filename: expandalias $
  3.  *      $Revision: 1.11 $
  4.  *      $Date: 1994/03/13 18:24:34 $
  5.  *
  6.  *      Copyright (C) 1993 by Peter Simons <simons@peti.GUN.de>
  7.  *
  8.  *      This program is free software; you can redistribute it and/or
  9.  *      modify it under the terms of the GNU General Public License as
  10.  *      published by the Free Software Foundation; either version 2 of
  11.  *      the License, or (at your option) any later version.
  12.  *
  13.  *      This program is distributed in the hope that it will be useful,
  14.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  *      General Public License for more details.
  17.  *
  18.  *      You should have received a copy of the GNU General Public License
  19.  *      along with this program; if not, write to the Free Software
  20.  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  *      $Id: expandalias.c,v 1.11 1994/03/13 18:24:34 simons Exp simons $
  23.  *
  24.  */
  25.  
  26. /**************************************************************************
  27.  *                                                                        *
  28.  * Sektion: Macros, Definitions, Includes, Structures                     *
  29.  *                                                                        *
  30.  **************************************************************************/
  31.  
  32. /************************************* Includes ***********/
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <fcntl.h>
  37. #include <time.h>
  38.  
  39. #include <libraries/netsupport.h>
  40. #include <proto/netsupport.h>
  41.  
  42. #include "protos.h"
  43.  
  44. /************************************* Defines ************/
  45. #define MAX_RECEIPIENTS 1024    /*
  46.                                  * max. number of receipients
  47.                                  */
  48.  
  49. #define HASHSIZE    256
  50. #define HASHMASK    (HASHSIZE-1)
  51.  
  52. #define HF_TERM     0x01        /* terminator name */
  53. #define HF_ALIAS    0x02        /* alias */
  54. #define HF_LOADED   0x04        /* def loaded */
  55. #define HF_NOEXPAND 0x08        /* do not expand alias */
  56.  
  57. typedef struct Hash {
  58.         struct Hash *Next;
  59.         short NumAlias;         /* # of aliases */
  60.         short Flags;
  61.         char *Name;             /* aliased user name */
  62.         union {
  63.                 struct Hash **Alias;    /* list of aliases */
  64.                 long Offset;            /* offset into file */
  65.         } u;
  66. } Hash;
  67.  
  68. /************************************* Prototypes *********/
  69. static void callBack(char *, long,  int);
  70. static Hash *FindHashObject(const char *);
  71. static void LoadHashObject(Hash *);
  72. static int HashFunc(const char *);
  73.  
  74. /************************************* global Variables ***/
  75. static const char __RCSId[] = "$Id: expandalias.c,v 1.11 1994/03/13 18:24:34 simons Exp simons $";
  76.  
  77. static char **new_receipients;
  78. static Hash *HashTab[HASHSIZE];
  79. static char Tmp[256];
  80.  
  81.  
  82. /**************************************************************************
  83.  *                                                                        *
  84.  * Sektion: Unterprogramme                                                *
  85.  *                                                                        *
  86.  **************************************************************************/
  87.  
  88. char **ExpandAliases(char *receipients[])
  89. {
  90.         char **new_receipients2;
  91.  
  92.         if (*receipients == NULL)
  93.                 return NULL;
  94.  
  95.         if ((new_receipients = malloc(sizeof(char *[MAX_RECEIPIENTS]))) == NULL)
  96.                  return NULL;
  97.  
  98.         new_receipients2 = new_receipients;
  99.         LoadAliases();
  100.         while (*receipients != NULL) {
  101.                 UserAliasList(*receipients, (int (*)(char *, long, int)) callBack, 0L, 1);
  102.                 receipients++;
  103.         }
  104.         *new_receipients = NULL;
  105.         return new_receipients2;
  106. }
  107.  
  108. static void callBack(char *name, long dummy, int show)
  109. {
  110.         switch (name[0]) {
  111.         case '|':
  112.         case '>':
  113.         case '<':
  114.                 break;
  115.         case '\\':
  116.                 ++name;
  117.         default:
  118.                 *new_receipients = name;
  119.                 new_receipients++;
  120.                 break;
  121.         }
  122. }
  123.  
  124. void LoadAliases(void)
  125. {
  126.         FILE *fi = fopen("UULib:Aliases", "r");
  127.         short i, j, k, line = 0;
  128.         long offset, newoffset = 0;
  129.         Hash *h;
  130.         char *buf = Tmp;
  131.  
  132.         if (fi == NULL) {
  133.                 MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "Can't open UULib:Aliases!");
  134.                 return;
  135.         }
  136.         while (fgets(buf, 256, fi)) {
  137.                 offset = newoffset;
  138.                 newoffset = ftell(fi);
  139.                 ++line;
  140.                 for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i) ;
  141.                 if (buf[i] == '#' || buf[i] == '\n')
  142.                         continue;
  143.                 for (j = i; buf[j] && buf[j] != ':'; ++j) ;
  144.                 if (buf[j] == 0) {
  145.                         MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "No Colon UULib:Aliases line %d.", line);
  146.                         continue;
  147.                 }
  148.                 buf[j] = 0;
  149.  
  150.                 k = HashFunc(buf + i);
  151.                 h = malloc(sizeof(Hash));
  152.                 h->Next = HashTab[k];
  153.                 h->NumAlias = 0;
  154.                 h->Flags = HF_ALIAS;
  155.                 h->Name = malloc(strlen(buf + i) + 1);
  156.                 if (buf[j + 1] == ':') {
  157.                         h->Flags |= HF_NOEXPAND;
  158.                         ++j;
  159.                 }
  160.                 h->u.Offset = offset + j + 1;
  161.                 strcpy(h->Name, buf + i);
  162.  
  163.                 HashTab[k] = h;
  164.  
  165.                 /*
  166.                  *  if trailing comma, list continues onto next line
  167.                  */
  168.  
  169.                 for (;;) {
  170.                         for (++j; buf[j]; ++j) ;
  171.                         while (buf[j - 1] == ' ' || buf[j - 1] == 9 || buf[j - 1] == '\n')
  172.                                 --j;
  173.                         if (buf[j - 1] != ',')
  174.                                 break;
  175.                         if (fgets(buf, 256, fi) == NULL)
  176.                                 break;
  177.                         newoffset = ftell(fi);
  178.                         j = 0;
  179.                 }
  180.         }
  181.         fclose(fi);
  182. }
  183.  
  184. static Hash *FindHashObject(const char *name)
  185. {
  186.         short k = HashFunc(name);
  187.         Hash *h;
  188.  
  189.         for (h = HashTab[k]; h; h = h->Next) {
  190.                 if (stricmp(name, h->Name) == 0)
  191.                         return (h);
  192.         }
  193.         return (NULL);
  194. }
  195.  
  196. static void LoadHashObject(Hash * hash)
  197. {
  198.         FILE *fi = fopen("UUlib:Aliases", "r");
  199.         char *buf = Tmp;
  200.         short i, j;
  201.         short c;
  202.         short numalloc = 4;
  203.         Hash **hv = malloc(sizeof(Hash *) * 4);
  204.         Hash *h;
  205.  
  206.         if (fi == NULL) {
  207.                 MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "Can't open UULib:Aliases!");
  208.                 return;
  209.         }
  210.  
  211.         hash->Flags |= HF_LOADED;
  212.         fseek(fi, hash->u.Offset, 0);
  213.  
  214.         while (fgets(buf, 256, fi)) {
  215.                 i = 0;
  216.                 c = 'x';
  217.  
  218.                 for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i) ;
  219.                 if (buf[i] == '#')
  220.                         continue;
  221.  
  222.                 for (;;) {
  223.                         while (buf[i] == ' ' || buf[i] == 9)
  224.                                 ++i;
  225.                         if (buf[i] == 0 || buf[i] == '\n' || buf[i] == '#')
  226.                                 break;
  227.  
  228.                         for (j = i; buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9 && buf[j] != ','; ++j) {
  229.                                 if (buf[j] == '\"') {
  230.                                         i = j + 1;
  231.                                         for (++j; buf[j] != '\n' && buf[j] != '\"'; ++j) ;
  232.                                         break;
  233.                                 }
  234.                         }
  235.                         c = buf[j];
  236.                         buf[j] = 0;
  237.  
  238.                         /*
  239.                          *  skip remaining junk before comma
  240.                          */
  241.  
  242.                         while (c && c != '\n' && c != ',')
  243.                                 c = buf[++j];
  244.  
  245.                         if ((h = FindHashObject(buf + i)) == NULL) {
  246.                                 short k = HashFunc(buf + i);
  247.  
  248.                                 h = malloc(sizeof(Hash));
  249.                                 h->Next = HashTab[k];
  250.                                 h->NumAlias = 0;
  251.                                 h->Flags = HF_TERM;
  252.                                 h->Name = malloc(strlen(buf + i) + 1);
  253.                                 h->u.Alias = NULL;
  254.                                 strcpy(h->Name, buf + i);
  255.  
  256.                                 HashTab[k] = h;
  257.                         }
  258.  
  259.                         if (hash->NumAlias == numalloc) {
  260.                                 Hash **hvo = hv;
  261.                                 short add = 4;
  262.  
  263.                                 hv = malloc(sizeof(Hash *) * (numalloc + add));
  264.                                 movmem((char *) hvo, (char *) hv, sizeof(Hash *) * numalloc);
  265.                                 numalloc += add;
  266.                         }
  267.                         hv[hash->NumAlias++] = h;
  268.  
  269.                         if (c == '\n' || c == 0)
  270.                                 i = j;
  271.                         else
  272.                                 i = j + 1;
  273.                 }
  274.                 if (c != ',')
  275.                         break;
  276.         }
  277.         hash->u.Alias = hv;
  278. }
  279.  
  280. int AliasExists(const char *user)
  281. {
  282.         if (FindHashObject(user))
  283.                 return (1);
  284.         return (0);
  285. }
  286.  
  287. /*
  288.  *  UserAliasList returns whether the 'user' should be displayed in the
  289.  *  To: field of the letter.  Normally it isn't, but if an alias is
  290.  *  specified to NOT expand on the To: field then the alias name itself
  291.  *  IS put on the To: field.
  292.  *
  293.  *  showto is passed from an upper level.  If set, the callback specifies
  294.  *  expansion (unless overriden by the alias), else the callback specifies
  295.  *  no expansion.
  296.  *
  297.  *  In the case where a high level alias is expanded but a low level alias
  298.  *  is not, the callback function is called for the low level alias with
  299.  *  a showto of -1, indicating that it should be placed on the To: list
  300.  *  WITHOUT being placed on the actual send-to list (because its expansion
  301.  *  is passed normally)
  302.  */
  303.  
  304. int UserAliasList(const char *user,
  305.                   int (*callback) (const char *, long, int),
  306.                   long arg,
  307.                   int showto)
  308. {
  309.         short i;
  310.         Hash *hash = FindHashObject(user);
  311.         static short stack;
  312.  
  313.         if (++stack == 32) {
  314.                 MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "UULib:Aliases recursion near user %s.", user);
  315.                 --stack;
  316.                 return 0;
  317.         }
  318.  
  319.         if (hash) {
  320.                 if ((hash->Flags & HF_TERM) == 0) {
  321.                         if ((hash->Flags & HF_LOADED) == 0)
  322.                                 LoadHashObject(hash);
  323.                         for (i = 0; i < hash->NumAlias; ++i) {
  324.                                 Hash *h = hash->u.Alias[i];
  325.                                 int r;
  326.  
  327.                                 if (showto)
  328.                                         r = UserAliasList(h->Name, callback, arg, !(hash->Flags & HF_NOEXPAND));
  329.                                 else
  330.                                         r = UserAliasList(h->Name, callback, arg, 0);
  331.                                 --stack;
  332.                                 if (r && showto && !(hash->Flags & HF_NOEXPAND))
  333.                                         (*callback) (h->Name, arg, -1);
  334.                         }
  335.                 }
  336.                 else {
  337.                         if (showto)
  338.                                 (*callback) (user, arg, !(hash->Flags & HF_NOEXPAND));
  339.                         else
  340.                                 (*callback) (user, arg, 0);
  341.                 }
  342.         }
  343.         else {
  344.                 (*callback) (user, arg, showto);
  345.         }
  346.         --stack;
  347.         if (hash && (hash->Flags & HF_NOEXPAND))
  348.                 return (1);
  349.         return (0);
  350. }
  351.  
  352. static int HashFunc(const char *str)
  353. {
  354.         unsigned long v = 0x14FBA5C3;
  355.  
  356.         while (*str) {
  357.                 v = (v << 5) ^ (*str & 0x1F) ^ (v >> 27);
  358.                 ++str;
  359.         }
  360.         return ((int) (v & HASHMASK));
  361. }
  362.